﻿using System;
using System.Dynamic;
using System.Linq;
using System.Web.Mvc;
using Xenta.Attributes;
using Xenta.Utils;
using Xenta.Web.Controllers;

namespace Xenta.Web.Areas.Wizard.Controllers
{
    [Authenticate]
    public sealed class BlogPostController : ExtController
    {
        #region GET/POST Actions

        [HttpGet, RestoreState]
        public ActionResult Create()
        {
            if(Svc.PublicationAuthor == null)
                return new HttpUnauthorizedResult();
            return View();
        }

        [HttpGet, RestoreState]
        public ActionResult Edit(int id)
        {
            if(Svc.PublicationAuthor == null)
                return new HttpUnauthorizedResult();
            var m = Svc.ProcessOperation("GetPublication", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m == null)
                return HttpNotFound();
            return View(m);
        }

        [HttpPost, PersistState]
        public ActionResult Create(string[] flags, string publishedOn)
        {
            if(Svc.PublicationAuthor == null)
                return new HttpUnauthorizedResult();
            try
            {
                var m = Svc.ProcessOperation("CreatePublication", new
                {
                    AuthorID = JDM.Int32(Svc.PublicationAuthor.EntityID),
                    FileGroupID = 0,
                    Code = StringHelper.Random(10),
                    Flags = flags.Union(new[]
                    {
                        "BlogPost"
                    }).Merge(","),
                    PublishedOn = Svc.DateTime(publishedOn)
                });
                return RedirectToAction(Loc.Act("Edit").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }).Localized());
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Create").Localized());
        }

        [HttpPost, PersistState]
        public ActionResult Update(int id,
            string[] flags,
            string publishedOn)
        {
            var m = Svc.ProcessOperation("GetPublication", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(m == null)
                return HttpNotFound();
            try
            {
                Svc.ProcessOperation("UpdatePublication", new
                {
                    AuthorID = JDM.Int32(m.Author.EntityID),
                    EntityID = JDM.Int32(m.EntityID),
                    FileGroupID = m.FileGroup != null ? JDM.Int32(m.FileGroup.EntityID) : 0,
                    Code = JDM.String(m.Code),
                    Flags = flags.Union(new[]
                    {
                        "BlogPost"
                    }).Merge(","),
                    PublishedOn = Svc.DateTime(publishedOn)
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }

            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }).Localized());
        }

        [HttpPost, PersistState, ValidateInput(false)]
        public ActionResult CreateTranslation(int postID,
            int languageID,
            string title,
            string description,
            string text)
        {
            try
            {
                Svc.ProcessOperation("CreatePublicationTranslation", new
                {
                    HolderID = postID,
                    LanguageID = languageID,
                    Title = HtmlUtility.StripTags(title),
                    Description = HtmlUtility.StripTags(description),
                    Text = HtmlUtility.Encode(text)
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = postID
            }).Localized());
        }

        [HttpPost, PersistState, ValidateInput(false)]
        public ActionResult UpdateTranslation(int id,
            int postID,
            int languageID,
            string title,
            string description,
            string text)
        {
            try
            {
                Svc.ProcessOperation("UpdatePublicationTranslation", new
                {
                    EntityID = id,
                    LanguageID = languageID,
                    Title = HtmlUtility.StripTags(title),
                    Description = HtmlUtility.StripTags(description),
                    Text = HtmlUtility.Encode(text)
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = postID
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult DeleteTranslation(int id, int postID)
        {
            try
            {
                Svc.ProcessOperation("DeletePublicationTranslation", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = postID
            }).Localized());
        }

        [HttpPost, PersistState]
        public ActionResult MapTag(int id, int tagID)
        {
            try
            {
                Svc.ProcessOperation("MapPublicationTagToPublication", new
                {
                    EntityID = id,
                    ChildID = tagID
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult UnmapTag(int id, int tagID)
        {
            try
            {
                Svc.ProcessOperation("UnmapPublicationTagFromPublication", new
                {
                    EntityID = id,
                    ChildID = tagID
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }).Localized());
        }

        [HttpPost, PersistState]
        public ActionResult MapAttribute(int id, int attributeID)
        {
            try
            {
                Svc.ProcessOperation("MapLookupAttributeToPublication", new
                {
                    EntityID = id,
                    ChildID = attributeID
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult UnmapAttribute(int id, int attributeID)
        {
            try
            {
                Svc.ProcessOperation("UnmapLookupAttributeFromPublication", new
                {
                    EntityID = id,
                    ChildID = attributeID
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }).Localized());
        }

        [HttpPost, PersistState]
        public ActionResult AttachFile(int id, int fileID)
        {
            var m = Svc.ProcessOperation("GetPublication", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(m == null)
                return HttpNotFound();

            int fileGroupID = m.FileGroup != null 
                ? JDM.Int32(m.FileGroup.EntityID) 
                : 0;
            if(fileGroupID == 0)
            {
                try
                {
                    fileGroupID = JDM.Int32(Svc.ProcessOperation("CreateFileGroup", new
                    {
                        OwnerID = JDM.Int32(Svc.FileOwner.EntityID),
                        Flags = "None"
                    }).EntityID);
                    Svc.ProcessOperation("UpdatePublication", new
                    {
                        AuthorID = JDM.Int32(m.Author.EntityID),
                        EntityID = JDM.Int32(m.EntityID),
                        FileGroupID = fileGroupID,
                        Code = JDM.String(m.Code),
                        Flags = JDM.String(m.Flags),
                        PublishedOn = JDM.DateTime(m.PublishedOn)
                    });
                }
                catch(Exception ex)
                {
                    ModelState.AddModelError("API", ex);
                }
            }
            if(fileGroupID != 0)
            {
                try
                {
                    Svc.ProcessOperation("MapFileToGroup", new
                    {
                        EntityID = fileGroupID,
                        ChildID = fileID
                    });
                }
                catch(Exception ex)
                {
                    ModelState.AddModelError("API", ex);
                }
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult DetachFile(int id, int fileID)
        {
            var m = Svc.ProcessOperation("GetPublication", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(m == null)
                return HttpNotFound();

            int fileGroupID = m.FileGroup != null 
                ? JDM.Int32(m.FileGroup.EntityID) 
                : 0;
            if(fileGroupID == 0)
            {
                return RedirectToAction(Loc.Act("Edit").Set(new
                {
                    id
                }).Localized());
            }
            try
            {
                Svc.ProcessOperation("UnmapFileFromGroup", new
                {
                    EntityID = fileGroupID,
                    ChildID = fileID
                });
                Svc.ProcessOperation("DeleteFile", new
                {
                    EntityID = fileID
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }).Localized());
        }

        #endregion

        #region Child Actions

        [ChildActionOnly]
        public ActionResult _Attachments(int id)
        {
            dynamic m = new ExpandoObject();

            m.Post = Svc.ProcessOperation("GetPublication", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(m.Post == null)
                return HttpNotFound();
            m.Attachments = Enumerable.Empty<dynamic>();
            if(m.Post.FileGroup != null)
            {
                m.Attachments = Svc.ProcessOperation("SearchFiles", new
                {
                    GroupID = JDM.Int32(m.Post.FileGroup.EntityID)
                }, new
                {
                    DisclosureLevel = "Base"
                }).Items;
            }
            return PartialView(m);
        }

        #endregion
    }
}
